#include <vector>
#include <string>
#include <iostream>
#include <stdexcept>
#include <cstdlib>

#include "ecs_app.hpp"
#include "first_app.hpp"
#include "test.hpp"
#include "thirdParty/thirdtest/third_test.h"

#define MAIN_EXEC_FLOW_FLAG 1

int main()
{
    std::cout << "----------------------------------------------------" << std::endl;
    std::cout << "main:THIRD_PARTY_LIB_TEST_FLAG: " << THIRD_PARTY_LIB_TEST_FLAG << std::endl;
    std::cout << "main:MAIN_EXEC_FLOW_FLAG: " << MAIN_EXEC_FLOW_FLAG << std::endl;
    if (MAIN_EXEC_FLOW_FLAG)
    {
        try
        {
            njm::ECSApp app{};
            app.run();
        }
        catch (const std::exception &e)
        {
            std::cerr << e.what() << '\n';
            return EXIT_FAILURE;
        }
        return EXIT_SUCCESS;
    }
    else
    {
        try
        {
            njm::FirstApp app{};
            app.run();
        }
        catch (const std::exception &e)
        {
            std::cerr << e.what() << '\n';
            return EXIT_FAILURE;
        }
        return EXIT_SUCCESS;
    }
}

/**
 * @brief Steps in rendering using vulkan:

VkInstance : Creating a vulkan Instance (context)
VkPhysicalDevice : Choose a physical device
VkDevice : Create a logical device(mapped to physical device)
VkQueue : Select queue families for chosen device
Native-Window : Create a window
VkSurfaceKHR : Create a window-surface
VkSwapChain : Create a swapchain
VkImage : Acquire image from swapchain
VkImageView : Create imageview for image acquired from swapchain
VkFrameBuffer : Create a framebuffer
VkRenderPass : Create a Renderpass
VkShaderModule : create shader-modules
VkPipeline : Create a Graphics pipeline
VkCommandPool : Create a command Pool
VkCommandBuffer : Get allocated commandbuffer from CommandPool
VkSubmitInfo, vkQueueSubmit() : submit commands from cmdbuf to queue
VkFence, VkSemaphore : for sync
Loop : Main loop to orchestrate all the above steps
 *
 */